package com.clstu.tankgame3;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;

public class MyPanel extends JPanel implements KeyListener,Runnable {//用画板来画坦克，镶嵌到画框里面才可以显示
    Hero hero = null;
    Vector<Tank> enemyTanks=new Vector();//泛型推荐 前写后不写
                                  //用vector容器才没有线程安全问题。
    Vector<Bom> boms = new Vector<>();

    //定义3张炸弹图片，用于产生爆炸效果
    Image image1  = null;
    Image image2  = null;
    Image image3  = null;

    public MyPanel(){
        hero=new Hero(100,100);//初始化自己的坦克
        int enemyTankSize = 8;
        for (int i = 0; i < enemyTankSize; i++) {
            enemyTanks.add(new EnemyTank((i+1)*100,500));
            new Thread(enemyTanks.get(i)).start();//启动线程
        }
        //初始化图片对象
        image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/image1.jfif"));
        image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/image2.png"));
        image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/image3.png"));
    }


    @Override
    public void paint(Graphics g) {
        super.paint(g);//初始化画笔g
        g.fillRect(0,0,1000,750);

        //if(hero.isLive()) {//根据自己的存活情况来决定是否需要画上自己的坦克
            drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 0);//绘画自己的坦克
       // }

        drawBullets(hero.getShots(),g);//画自己的所有子弹

        if(enemyTanks.size()!=0){//绘制所有的 敌方坦克 和 敌方坦克的子弹
            for (int i = 0; i < enemyTanks.size(); i++) {
                Tank enemyTank = enemyTanks.get(i);
                if(enemyTank.isLive()) {
                    drawTank(enemyTank.getX(),enemyTank.getY(),g,enemyTank.getDirect(),1);
                    drawBullets(enemyTank.getShots(),g);
                }
                else {
                    enemyTanks.remove(enemyTank);
                }
            }
        }

        if(boms.size()>0){
            try {
                Thread.sleep(10);//因为image的问题，第一次击中敌方tank不会有爆炸效果，
                                      //休眠10ms等等就有了
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for (int i=0 ;i< boms.size();i++){
                Bom b = boms.get(i);
                if(b.isLive()){
                    if(b.getLife()>6){
                        g.drawImage(image1,b.getX(),b.getY(),60,60,this);
                    }else if(b.getLife()>3){
                        g.drawImage(image2,b.getX(),b.getY(),60,60,this);
                    }else {
                        g.drawImage(image3,b.getX(),b.getY(),60,60,this);
                    }
                    b.lifeDown();//生命值--
                }else {
                    boms.remove(b);
                }
            }
        }

    }

    /**
     *
     * @param x 横坐标
     * @param y 纵坐标
     * @param g 画笔
     * @param direct 方向
     * @param type 类型
     */
    private void drawTank(int x,int y,Graphics g,int direct,int type){//根据参数画出坦克，通过被paint调用画出
        switch (type){
            case 0:
                g.setColor(Color.cyan);
                break;
            case 1:
                g.setColor(Color.yellow);
                break;
        }
        switch (direct){//方向（0上1左2下3右）
            case 0://上
                g.fill3DRect(x,y,10,60,false);
                g.fill3DRect(x+30,y,10,60,false);
                g.fill3DRect(x+10,y+10,20,40,false);
                g.drawOval(x+10,y+20,20,20);
                g.drawLine(x+20,y,x+20,y+30);
                break;
            case 1://左
                g.fill3DRect(x,y,60,10,false);
                g.fill3DRect(x,y+30,60,10,false);
                g.fill3DRect(x+10,y+10,40,20,false);
                g.drawOval(x+20,y+10,20,20);
                g.drawLine(x,y+20,x+30,y+20);
                break;
            case 2://下
                g.fill3DRect(x,y,10,60,false);
                g.fill3DRect(x+30,y,10,60,false);
                g.fill3DRect(x+10,y+10,20,40,false);
                g.drawOval(x+10,y+20,20,20);
                g.drawLine(x+20,y+60,x+20,y+30);
                break;
            case 3://右
                g.fill3DRect(x,y,60,10,false);
                g.fill3DRect(x,y+30,60,10,false);
                g.fill3DRect(x+10,y+10,40,20,false);
                g.drawOval(x+20,y+10,20,20);
                g.drawLine(x+60,y+20,x+30,y+20);
                break;
            default:
                System.out.println("还没有设计出来~~");
                break;
        }
    }

    private void drawBullet(Shot shot,Graphics g){//根据传入的子弹画出它(主要是颜色不同）
        if (shot.isAlive()) {
            g.setColor(shot.getColor());
            g.fill3DRect(shot.getX(),shot.getY(),5,5,false);
        }
    }

    public void drawBullets(Vector<Shot> shots,Graphics g){//绘制一堆子弹
        if(shots.size()>0) {
            for (int j = 0 ;j<shots.size();j++) {
                Shot s = shots.get(j);
                if (s.isAlive()) {
                    drawBullet(s,g);
                }
                else {
                    shots.remove(s);
                }
            }
        }
    }

    //判断一颗子弹是否击中敌人
    public void hitTank(Shot shot,Tank tank){

        //坦克的方向不同覆盖的形状也不一样,需要分开判断
        switch (tank.getDirect()){
            case 0:
            case 2:
                if(shot.getX()>tank.getX() && shot.getX()<tank.getX()+40
                && shot.getY()>tank.getY()&& shot.getY()<tank.getY()+60){
                    shot.setAlive(false);
                    tank.setLive(false);
                    Bom bom = new Bom(tank.getX(), tank.getY());
                    boms.add(bom);
                }
                break;
            case 1:
            case 3:
                if(shot.getX()>tank.getX() && shot.getX()<tank.getX()+60
                        && shot.getY()>tank.getY()&& shot.getY()<tank.getY()+40){
                    shot.setAlive(false);
                    tank.setLive(false);
                    Bom bom = new Bom(tank.getX(), tank.getY());
                    boms.add(bom);
                }
                break;
        }
    }

    //判断一个坦克的所有子弹是否有击中敌人
    public void hitsTank(Vector<Shot> shots,Vector<Tank> tanks){
        if(shots.size()>0) {

            for (Shot s:shots) {
                if (s.isAlive()){

                    for (Tank t:tanks) {
                        if(t.isLive()){
                            hitTank(s,t);
                        }
                    }
                }
            }
        }
    }

    //判断是否有敌方坦克击中自己
    public void hitHero(Vector<Tank> enemyTanks, Tank hero){
        if (enemyTanks.size()>0){

            for(Tank e: enemyTanks){//遍历所有敌方坦克
                if (e.getShots().size()>0){

                    for (Shot s:e.getShots()){//遍历敌方坦克的子弹
                        if (s.isAlive()){
                            hitTank(s,hero);
                        }
                    }
                }
            }
        }
    }


    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
          if(e.getKeyCode()==KeyEvent.VK_W){
              hero.setDirect(0);
              hero.moveUP();
          }else if(e.getKeyCode()==KeyEvent.VK_A){
              hero.setDirect(1);
              hero.moveLeft();
          }else if(e.getKeyCode()==KeyEvent.VK_S){
              hero.setDirect(2);
              hero.moveDown();
          }else if(e.getKeyCode()==KeyEvent.VK_D){
              hero.setDirect(3);
              hero.moveRight();
          }
          if(e.getKeyCode()==KeyEvent.VK_J){
              hero.shotEnemyTank();
          }
          this.repaint();//重新绘制更新后的画面
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            hitsTank(hero.getShots(),enemyTanks);//判断是否有敌方坦克被击中
            hitHero(enemyTanks,hero);             //判断自己是否被敌方坦克击中
            repaint();
        }
    }
}
